/*
 * UDP endpoint
 *
 * A simple UDP endpoint example using the WiShield 1.0
 */
 
 
extern "C" {
   #include "uip.h"
   #include <string.h>
   #include "udpapp.h"
   #include "config.h"
}
#include <WiShield.h>

#define WIRELESS_MODE_INFRA	1
#define WIRELESS_MODE_ADHOC	2

#define PPM_MAX 2000
#define PPM_MIN 1000
#define CHANNELS 6
#include <Wire.h>

 #define STATE_INIT				0
 #define STATE_LISTENING         1
 #define STATE_HELLO_RECEIVED	2
 #define STATE_NAME_RECEIVED		3

// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {192,168,1,2};	// IP address of WiShield
unsigned char gateway_ip[] = {192,168,1,1};	// router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0};	// subnet mask for the local network
const prog_char ssid[] PROGMEM = {"DroneAP"};		// max 32 bytes

unsigned char security_type = 0;	// 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2

// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"12345678"};	// max 64 characters

// WEP 128-bit keys
// sample HEX keys

prog_uchar wep_keys[] PROGMEM = {	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,	// Key 0
									0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x00,	// Key 1
									0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x00,	// Key 2
									0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x00	// Key 3
								};

// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_ADHOC;

unsigned char ssid_len;
unsigned char security_passphrase_len;
//---------------------------------------------------------------------------

uint16_t data[] = {1000,1100,1200,1300,1400,1500};

long currentTime;
long previousTime;

void setup()
{
  Serial.begin(57600);  
  Serial.println("Init Module started");
  
  WiFi.init();
  
  Serial.println("I2C Init");
  //Init as I2C Slave
  //Wire.begin(2);
  //Wire.onRequest(requestEvent);
  //Wire.onReceive(receiveEvent);
  Serial.println("Init Module finished");
  
  previousTime = micros();
}


void loop()
{
  WiFi.run();
  
  currentTime = micros();
  long deltaTime = currentTime - previousTime;
  
  if (deltaTime >= 5000000) {
    for(int i = 0; i < 6; i++){
      if(data[i]>= PPM_MAX){
        data[i] = PPM_MIN;
      }else{
        data[i]++; 
      }
    } 
    //memset(0x00, 0x00, 0x00);
    //uip_send(0x00,0x00);
     Serial.println("udpsample: sending data...");

     Serial.println("suceeded");
    previousTime = currentTime;
  }
  
 
}


//I2C Request Handler
void requestEvent()
{  
  //digitalWrite(13, !digitalRead(13));
  byte bdata[12];
  for(int i = 0; i < CHANNELS; i++){
    bdata[i*2] = data[i];
    bdata[i*2+1] = data[i]>>8;
  }
  Wire.send(bdata, 12);
  Serial.println("request answerd");
}
//I2C Resieve Handler
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.receive(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.receive();    // receive byte as an integer
  Serial.println(x);         // print the integer
}



extern "C"
{
  static struct udpapp_state s;
 
 void dummy_app_appcall(void)
 {
 }
 
 void udpapp_init(void)
 {
 	uip_ipaddr_t addr;
 	struct uip_udp_conn *c;
 
 	uip_ipaddr(&addr, 192,168,1,153);
 	c = uip_udp_new(&addr, HTONS(0));
 	if(c != NULL) {
 		uip_udp_bind(c, HTONS(12344));
 	}
 

	s.state = STATE_INIT;

	PT_INIT(&s.pt);
}

static unsigned char parse_msg(void)
{
	if (memcmp(uip_appdata, "Hello", 5) == 0) {
		return 1;
	}

	return 0;
}

static void send_request(void)
{
	char str[] = "Hello. What is your name?\n";

	memcpy(uip_appdata, str, strlen(str));
	uip_send(uip_appdata, strlen(str));
}

static void send_response(void)
{
  	char str[] = "Hello. Bla\n";

	memcpy(uip_appdata, str, strlen(str));
	uip_send(uip_appdata, strlen(str));

}

static PT_THREAD(handle_connection(void))
{
	PT_BEGIN(&s.pt);

	s.state = STATE_LISTENING;

	do {
		PT_WAIT_UNTIL(&s.pt, uip_newdata());

		if(uip_newdata() && parse_msg()) {
			s.state = STATE_HELLO_RECEIVED;
			uip_flags &= (~UIP_NEWDATA);
			break;
		}
	} while(s.state != STATE_HELLO_RECEIVED);

	do {
		send_request();
		PT_WAIT_UNTIL(&s.pt, uip_newdata());

		if(uip_newdata()) {
			s.state = STATE_NAME_RECEIVED;
			uip_flags &= (~UIP_NEWDATA);
			break;
		}
	} while(s.state != STATE_NAME_RECEIVED);

	send_response();

	s.state = STATE_INIT;

	PT_END(&s.pt);
}

void udpapp_appcall(void)
{
	handle_connection();
}
  /*
   void udpapp_init(void)
   {
      uip_ipaddr_t addr;
      struct uip_udp_conn *c;
    
      uip_ipaddr(&addr, 192,168,1,153);
      c = uip_udp_new(&addr, HTONS(12345));
      if(c != NULL) {
        uip_udp_bind(c, HTONS(12344));
      }
   }

   void send_data(void)
   {
      Serial.println("udpsample: sending data...");
      char str[] = "udpsample: this is some UDP data...";
      memcpy(uip_appdata, str, strlen(str));
      uip_send(uip_appdata, strlen(str));
   }

 static unsigned char parse_msg(void)
 {
 	if (memcmp(uip_appdata, "Pong", 5) == 0) {
 		return 1;
 	}
 
 	return 0;
 }

   void udpapp_appcall(void)
   {
     Serial.println("Resieved String");
     send_data();
     if(uip_newdata() && parse_msg()) {
       uip_flags &= (~UIP_NEWDATA);
       Serial.println("Resieved Pong");
     }
   }   

   void dummy_app_appcall(void)
   {

   }   
   */
}




